package com.derbysoft.lowcostadapter.dswitch2.translator.impl;

import com.derbysoft.lowcostadapter.commons.dto.BookResponse;
import com.derbysoft.lowcostadapter.commons.dto.BookResult;
import com.derbysoft.lowcostadapter.dswitch2.translator.Translator;
import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.core.GenericRS;
import com.derbysoft.remote.dswitch.core.ResponseHeader;
import com.derbysoft.remote.dswitch.core.SuccessDTO;
import com.derbysoft.remote.dswitch.generic.constants.TransactionStatusType;
import com.derbysoft.remote.dswitch.generic.constants.UniqueIDType;
import com.derbysoft.remote.dswitch.generic.dto.SimpleAmountDTO;
import com.derbysoft.remote.dswitch.generic.dto.UniqueIDDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationIDDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationRQ;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationRS;
import com.derbysoft.remote.dswitch.hotel.dto.TotalDTO;
import com.derbysoft.remote.share.Currency;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Component("ds2HotelReservationRSTranslator")
public class HotelReservationRSTranslatorImpl implements Translator<BookResponse, GenericRS<HotelReservationRS>, GenericRQ<HotelReservationRQ>> {
    private static final String LOW_COST_PASSPORT = "lowcostbeds";

    @Override
    public GenericRS<HotelReservationRS> translate(BookResponse bookResponse, GenericRQ<HotelReservationRQ> rq) {
        GenericRS<HotelReservationRS> rs = new GenericRS<HotelReservationRS>();
        rs.setPayload(createPayload(bookResponse.getBookResult(), rq));
        rs.setSuccess(new SuccessDTO());
        rs.setHeader(createHeader(rq));
        return rs;
    }

    protected ResponseHeader createHeader(GenericRQ<HotelReservationRQ> rq) {
        ResponseHeader responseHeader = new ResponseHeader();
        responseHeader.setTaskId(rq.getHeader().getTaskId());
        return responseHeader;
    }

    private HotelReservationRS createPayload(BookResult bookResult, GenericRQ<HotelReservationRQ> rq) {
        HotelReservationRS hotelReservationRS = new HotelReservationRS();

        hotelReservationRS.setOriginalBuyer(rq.getPayload().getOriginalBuyer());
        hotelReservationRS.setOriginalProvider(new UniqueIDDTO(LOW_COST_PASSPORT, UniqueIDType.WHOLESALER));
        hotelReservationRS.setResStatusType(TransactionStatusType.COMMITTED);
        hotelReservationRS.setHotelReservation(rq.getPayload().getHotelReservation());

        ArrayList<HotelReservationIDDTO> hotelReservationIDDTOs = new ArrayList<HotelReservationIDDTO>();
        HotelReservationIDDTO reservationID = findReservationID(rq.getPayload().getHotelReservationIDs(), UniqueIDType.ERSP);
        if (reservationID != null) {
            hotelReservationIDDTOs.add(reservationID);
        }

        hotelReservationIDDTOs.add(new HotelReservationIDDTO(UniqueIDType.HOTEL, bookResult.getBookingReference()));

        hotelReservationRS.setHotelReservationIDs(hotelReservationIDDTOs);

        hotelReservationRS.setTotal(createTotal(bookResult));

        return hotelReservationRS;
    }

    private TotalDTO createTotal(BookResult bookResult) {
        TotalDTO totalDTO = new TotalDTO();
        totalDTO.setTotalAmount(createAmount(bookResult.getTotalPrice()));
        totalDTO.setPureAmount(createAmount(bookResult.getTotalPrice()));
        totalDTO.setTotalCommission(createAmount(bookResult.getTotalCommission()));
        return totalDTO;
    }

    private SimpleAmountDTO createAmount(BigDecimal totalPrice) {
        return new SimpleAmountDTO(totalPrice, Currency.GBP);
    }

    private HotelReservationIDDTO findReservationID(List<HotelReservationIDDTO> hotelReservationIDDTOs, UniqueIDType resIDType) {
        for (HotelReservationIDDTO hotelReservationIDDTO : hotelReservationIDDTOs) {
            if (hotelReservationIDDTO.getResIDType() == resIDType) {
                return hotelReservationIDDTO;
            }
        }
        return null;
    }
}
